home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gslib.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  30.4 KB  |  1,102 lines

  1. /* Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gslib.c,v 1.3 2000/09/19 19:00:29 lpd Exp $ */
  20. /* Test program for Ghostscript library */
  21. /* Capture stdin/out/err before gsio.h redefines them. */
  22. #include "stdio_.h"
  23. static FILE *real_stdin, *real_stdout, *real_stderr;
  24. static void
  25. get_real(void)
  26. {
  27.     real_stdin = stdin, real_stdout = stdout, real_stderr = stderr;
  28. }
  29. #include "math_.h"
  30. #include "string_.h"
  31. #include "gx.h"
  32. #include "gp.h"
  33. #include "gsalloc.h"
  34. #include "gscdefs.h"
  35. #include "gserrors.h"
  36. #include "gslib.h"
  37. #include "gsmatrix.h"
  38. #include "gsstate.h"
  39. #include "gscspace.h"
  40. #include "gscssub.h"
  41. #include "gscolor2.h"
  42. #include "gscoord.h"
  43. #include "gscie.h"
  44. #include "gscrd.h"
  45. #include "gsiparm3.h"
  46. #include "gsiparm4.h"
  47. #include "gsparam.h"
  48. #include "gspaint.h"
  49. #include "gspath.h"
  50. #include "gspath2.h"
  51. #include "gsrop.h"
  52. #include "gsstruct.h"
  53. #include "gsutil.h"
  54. #include "gxalloc.h"
  55. #include "gxdcolor.h"        /* for gx_device_white/black */
  56. #include "gxdevice.h"
  57. #include "gxht.h"        /* for gs_halftone */
  58. #include "gdevbbox.h"
  59. #include "gdevcmap.h"
  60. #include "gshtx.h"
  61.  
  62. /* Define whether we are processing captured data. */
  63. /*#define CAPTURE */
  64.  
  65. /* Test programs */
  66. private int test1(P2(gs_state *, gs_memory_t *));    /* kaleidoscope */
  67. private int test2(P2(gs_state *, gs_memory_t *));    /* pattern fill */
  68. private int test3(P2(gs_state *, gs_memory_t *));    /* RasterOp */
  69. private int test4(P2(gs_state *, gs_memory_t *));    /* set resolution */
  70. private int test5(P2(gs_state *, gs_memory_t *));    /* images */
  71. private int test6(P2(gs_state *, gs_memory_t *));    /* CIE API, snapping */
  72. private int test7(P2(gs_state *, gs_memory_t *));    /* non-monot HT */
  73. private int test8(P2(gs_state *, gs_memory_t *));    /* transp patterns */
  74.  
  75. #ifdef CAPTURE
  76. #include "k/capture.c"
  77. private int test10(P2(gs_state *, gs_memory_t *));    /* captured data */
  78.  
  79. #endif
  80. private int (*tests[]) (P2(gs_state *, gs_memory_t *)) =
  81. {
  82.     test1, test2, test3, test4, test5,
  83.     test6, test7, test8, 0
  84. #ifdef CAPTURE
  85.     test10
  86. #endif
  87. };
  88.  
  89. /* Include the extern for the device list. */
  90. extern_gs_lib_device_list();
  91.  
  92. /* Forward references */
  93. private float odsf(P2(floatp, floatp));
  94.  
  95. int
  96. main(int argc, const char *argv[])
  97. {
  98.     char achar;
  99.     gs_ref_memory_t *imem;
  100.  
  101. #define mem ((gs_memory_t *)imem)
  102.     gs_state *pgs;
  103.     const gx_device *const *list;
  104.     gx_device *dev;
  105.     gx_device_bbox *bbdev;
  106.     int code;
  107.  
  108.     gp_init();
  109.     get_real();
  110.     gs_stdin = real_stdin;
  111.     gs_stdout = real_stdout;
  112.     gs_stderr = real_stderr;
  113.     gs_lib_init(stdout);
  114.     if (argc < 2 || (achar = argv[1][0]) < '1' ||
  115.     achar > '0' + countof(tests)
  116.     ) {
  117.     lprintf1("Usage: gslib 1..%c\n", '0' + countof(tests));
  118.     exit(1);
  119.     }
  120.     gs_debug['@'] = 1;
  121.     gs_debug['?'] = 1;
  122. /*gs_debug['B'] = 1; *//****** PATCH ******/
  123. /*gs_debug['L'] = 1; *//****** PATCH ******/
  124.     imem = ialloc_alloc_state(&gs_memory_default, 20000);
  125.     imem->space = 0;
  126.     /*
  127.      * gs_iodev_init must be called after the rest of the inits, for
  128.      * obscure reasons that really should be documented!
  129.      */
  130.     gs_iodev_init(mem);
  131. /****** WRONG ******/
  132.     gs_lib_device_list(&list, NULL);
  133.     gs_copydevice(&dev, list[0], mem);
  134.     gx_device_fill_in_procs(dev);
  135.     bbdev =
  136.     gs_alloc_struct_immovable(mem, gx_device_bbox, &st_device_bbox,
  137.                   "bbox");
  138.     gx_device_bbox_init(bbdev, dev);
  139.     /* Print out the device name just to test the gsparam.c API. */
  140.     {
  141.     gs_c_param_list list;
  142.     gs_param_string nstr;
  143.  
  144.     gs_c_param_list_write(&list, mem);
  145.     code = gs_getdeviceparams(dev, (gs_param_list *) & list);
  146.     if (code < 0) {
  147.         lprintf1("getdeviceparams failed! code = %d\n", code);
  148.         exit(1);
  149.     }
  150.     gs_c_param_list_read(&list);
  151.     code = param_read_string((gs_param_list *) & list, "Name", &nstr);
  152.     if (code < 0) {
  153.         lprintf1("reading Name failed! code = %d\n", code);
  154.         exit(1);
  155.     }
  156.     dputs("Device name = ");
  157.     debug_print_string(nstr.data, nstr.size);
  158.     dputs("\n");
  159.     gs_c_param_list_release(&list);
  160.     }
  161.     /*
  162.      * If this is a device that takes an OutputFile, set the OutputFile
  163.      * to "-" in the copy.
  164.      */
  165.     {
  166.     gs_c_param_list list;
  167.     gs_param_string nstr;
  168.  
  169.     gs_c_param_list_write(&list, mem);
  170.     param_string_from_string(nstr, "-");
  171.     code = param_write_string((gs_param_list *)&list, "OutputFile", &nstr);
  172.     if (code < 0) {
  173.         lprintf1("writing OutputFile failed! code = %d\n", code);
  174.         exit(1);
  175.     }
  176.     gs_c_param_list_read(&list);
  177.     code = gs_putdeviceparams(dev, (gs_param_list *)&list);
  178.     gs_c_param_list_release(&list);
  179.     if (code < 0 && code != gs_error_undefined) {
  180.         lprintf1("putdeviceparams failed! code = %d\n", code);
  181.         exit(1);
  182.     }
  183.     }
  184.     dev = (gx_device *) bbdev;
  185.     pgs = gs_state_alloc(mem);
  186.     gs_setdevice_no_erase(pgs, dev);    /* can't erase yet */
  187.     {
  188.     gs_point dpi;
  189.     gs_screen_halftone ht;
  190.  
  191.     gs_dtransform(pgs, 72.0, 72.0, &dpi);
  192.     ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001;
  193.     ht.angle = 0;
  194.     ht.spot_function = odsf;
  195.     gs_setscreen(pgs, &ht);
  196.     }
  197.     /* gsave and grestore (among other places) assume that */
  198.     /* there are at least 2 gstates on the graphics stack. */
  199.     /* Ensure that now. */
  200.     gs_gsave(pgs);
  201.     gs_erasepage(pgs);
  202.  
  203.     code = (*tests[achar - '1']) (pgs, mem);
  204.     gs_output_page(pgs, 1, 1);
  205.     {
  206.     gs_rect bbox;
  207.  
  208.     gx_device_bbox_bbox(bbdev, &bbox);
  209.     dprintf4("Bounding box: [%g %g %g %g]\n",
  210.          bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
  211.     }
  212.     if (code)
  213.     dprintf1("**** Test returned code = %d.\n", code);
  214.     dputs("Done.  Press <enter> to exit.");
  215.     getchar();
  216.     gs_lib_finit(0, 0);
  217.     return 0;
  218. #undef mem
  219. }
  220. /* Ordered dither spot function */
  221. private float
  222. odsf(floatp x, floatp y)
  223. {
  224.     static const byte dither[256] =
  225.     {
  226.     0x0E, 0x8E, 0x2E, 0xAE, 0x06, 0x86, 0x26, 0xA6, 0x0C, 0x8C, 0x2C, 0xAC, 0x04, 0x84, 0x24, 0xA4,
  227.     0xCE, 0x4E, 0xEE, 0x6E, 0xC6, 0x46, 0xE6, 0x66, 0xCC, 0x4C, 0xEC, 0x6C, 0xC4, 0x44, 0xE4, 0x64,
  228.     0x3E, 0xBE, 0x1E, 0x9E, 0x36, 0xB6, 0x16, 0x96, 0x3C, 0xBC, 0x1C, 0x9C, 0x34, 0xB4, 0x14, 0x94,
  229.     0xFE, 0x7E, 0xDE, 0x5E, 0xF6, 0x76, 0xD6, 0x56, 0xFC, 0x7C, 0xDC, 0x5C, 0xF4, 0x74, 0xD4, 0x54,
  230.     0x01, 0x81, 0x21, 0xA1, 0x09, 0x89, 0x29, 0xA9, 0x03, 0x83, 0x23, 0xA3, 0x0B, 0x8B, 0x2B, 0xAB,
  231.     0xC1, 0x41, 0xE1, 0x61, 0xC9, 0x49, 0xE9, 0x69, 0xC3, 0x43, 0xE3, 0x63, 0xCB, 0x4B, 0xEB, 0x6B,
  232.     0x31, 0xB1, 0x11, 0x91, 0x39, 0xB9, 0x19, 0x99, 0x33, 0xB3, 0x13, 0x93, 0x3B, 0xBB, 0x1B, 0x9B,
  233.     0xF1, 0x71, 0xD1, 0x51, 0xF9, 0x79, 0xD9, 0x59, 0xF3, 0x73, 0xD3, 0x53, 0xFB, 0x7B, 0xDB, 0x5B,
  234.     0x0D, 0x8D, 0x2D, 0xAD, 0x05, 0x85, 0x25, 0xA5, 0x0F, 0x8F, 0x2F, 0xAF, 0x07, 0x87, 0x27, 0xA7,
  235.     0xCD, 0x4D, 0xED, 0x6D, 0xC5, 0x45, 0xE5, 0x65, 0xCF, 0x4F, 0xEF, 0x6F, 0xC7, 0x47, 0xE7, 0x67,
  236.     0x3D, 0xBD, 0x1D, 0x9D, 0x35, 0xB5, 0x15, 0x95, 0x3F, 0xBF, 0x1F, 0x9F, 0x37, 0xB7, 0x17, 0x97,
  237.     0xFD, 0x7D, 0xDD, 0x5D, 0xF5, 0x75, 0xD5, 0x55, 0xFF, 0x7F, 0xDF, 0x5F, 0xF7, 0x77, 0xD7, 0x57,
  238.     0x02, 0x82, 0x22, 0xA2, 0x0A, 0x8A, 0x2A, 0xAA, 0x00, 0x80, 0x20, 0xA0, 0x08, 0x88, 0x28, 0xA8,
  239.     0xC2, 0x42, 0xE2, 0x62, 0xCA, 0x4A, 0xEA, 0x6A, 0xC0, 0x40, 0xE0, 0x60, 0xC8, 0x48, 0xE8, 0x68,
  240.     0x32, 0xB2, 0x12, 0x92, 0x3A, 0xBA, 0x1A, 0x9A, 0x30, 0xB0, 0x10, 0x90, 0x38, 0xB8, 0x18, 0x98,
  241.     0xF2, 0x72, 0xD2, 0x52, 0xFA, 0x7A, 0xDA, 0x5A, 0xF0, 0x70, 0xD0, 0x50, 0xF8, 0x78, 0xD8, 0x58
  242.     };
  243.     int i = (int)((x + 1) * 7.9999);
  244.     int j = (int)((y + 1) * 7.9999);
  245.  
  246.     return dither[16 * i + j] / 256.0;
  247. }
  248.  
  249. /* Fill a rectangle. */
  250. private int
  251. fill_rect1(gs_state * pgs, floatp x, floatp y, floatp w, floatp h)
  252. {
  253.     gs_rect r;
  254.  
  255.     r.q.x = (r.p.x = x) + w;
  256.     r.q.y = (r.p.y = y) + h;
  257.     return gs_rectfill(pgs, &r, 1);
  258. }
  259.  
  260. /* Stubs for GC */
  261. const gs_ptr_procs_t ptr_struct_procs =
  262. {NULL, NULL, NULL};
  263. const gs_ptr_procs_t ptr_string_procs =
  264. {NULL, NULL, NULL};
  265. const gs_ptr_procs_t ptr_const_string_procs =
  266. {NULL, NULL, NULL};
  267. void *                /* obj_header_t * */
  268. gs_reloc_struct_ptr(const void * /* obj_header_t * */ obj, gc_state_t * gcst)
  269. {
  270.     return (void *)obj;
  271. }
  272. void
  273. gs_reloc_string(gs_string * sptr, gc_state_t * gcst)
  274. {
  275. }
  276. void
  277. gs_reloc_const_string(gs_const_string * sptr, gc_state_t * gcst)
  278. {
  279. }
  280.  
  281. /* Other stubs */
  282. void
  283. gs_exit(int exit_status)
  284. {
  285.     gs_lib_finit(exit_status, 0);
  286.     exit(exit_status);
  287. }
  288.  
  289.  
  290. /* Return the number with the magnitude of x and the sign of y. */
  291. /* This is a BSD addition to libm; not all compilers have it. */
  292. private double
  293. gs_copysign(floatp x, floatp y)
  294. {
  295.    return ( y >= 0  ? fabs(x) : -fabs(x) );
  296. }
  297.  
  298.  
  299. /* ---------------- Test program 1 ---------------- */
  300. /* Draw a colored kaleidoscope. */
  301.  
  302. /* Random number generator */
  303. private long rand_state = 1;
  304. private long
  305. rand(void)
  306. {
  307. #define A 16807
  308. #define M 0x7fffffff
  309. #define Q 127773        /* M / A */
  310. #define R 2836            /* M % A */
  311.     rand_state = A * (rand_state % Q) - R * (rand_state / Q);
  312.     /* Note that rand_state cannot be 0 here. */
  313.     if (rand_state <= 0)
  314.     rand_state += M;
  315. #undef A
  316. #undef M
  317. #undef Q
  318. #undef R
  319.     return rand_state;
  320. }
  321. private int
  322. test1(gs_state * pgs, gs_memory_t * mem)
  323. {
  324.     int n;
  325.  
  326.     gs_scale(pgs, 72.0, 72.0);
  327.     gs_translate(pgs, 4.25, 5.5);
  328.     gs_scale(pgs, 4.0, 4.0);
  329.     gs_newpath(pgs);
  330.     for (n = 200; --n >= 0;) {
  331.     int j;
  332.  
  333. #define rf() (rand() / (1.0 * 0x10000 * 0x8000))
  334.     double r = rf(), g = rf(), b = rf();
  335.     double x0 = rf(), y0 = rf(), x1 = rf(), y1 = rf(), x2 = rf(), y2 = rf();
  336.  
  337.     gs_setrgbcolor(pgs, r, g, b);
  338.     for (j = 0; j < 6; j++) {
  339.         gs_gsave(pgs);
  340.         gs_rotate(pgs, 60.0 * j);
  341.         gs_moveto(pgs, x0, y0);
  342.         gs_lineto(pgs, x1, y1);
  343.         gs_lineto(pgs, x2, y2);
  344.         gs_fill(pgs);
  345.         gs_grestore(pgs);
  346.     }
  347.     }
  348. #undef mem
  349.     return 0;
  350. }
  351.  
  352. /* ---------------- Test program 2 ---------------- */
  353. /* Fill an area with a pattern. */
  354.  
  355. private int
  356. test2(gs_state * pgs, gs_memory_t * mem)
  357. {
  358.     gs_client_color cc;
  359.     gx_tile_bitmap tile;
  360.     /*const */ byte tpdata[] =
  361.     {
  362.     /* Define a pattern that looks like this:
  363.        ..xxxx
  364.        .....x
  365.        .....x
  366.        ..xxxx
  367.        .x....
  368.        x.....
  369.      */
  370.     0x3c, 0, 0, 0, 0x04, 0, 0, 0, 0x04, 0, 0, 0, 0x3c, 0, 0, 0,
  371.     0x40, 0, 0, 0, 0x80, 0, 0, 0
  372.     };
  373.  
  374.     gs_newpath(pgs);
  375.     gs_moveto(pgs, 100.0, 300.0);
  376.     gs_lineto(pgs, 500.0, 500.0);
  377.     gs_lineto(pgs, 200.0, 100.0);
  378.     gs_lineto(pgs, 300.0, 500.0);
  379.     gs_lineto(pgs, 500.0, 200.0);
  380.     gs_closepath(pgs);
  381.     gs_setrgbcolor(pgs, 0.0, 0.0, 0.0);
  382.     gs_gsave(pgs);
  383.     gs_fill(pgs);
  384.     gs_grestore(pgs);
  385.     tile.data = tpdata;
  386.     tile.raster = 4;
  387.     tile.size.x = tile.rep_width = 6;
  388.     tile.size.y = tile.rep_height = 6;
  389.     tile.id = gx_no_bitmap_id;
  390.     gs_makebitmappattern(&cc, &tile, true, pgs, NULL);
  391.     /* Note: color space is DeviceRGB */
  392.     cc.paint.values[0] = 0.0;
  393.     cc.paint.values[1] = 1.0;
  394.     cc.paint.values[2] = 1.0;
  395.     gs_setpattern(pgs, &cc);
  396.     gs_eofill(pgs);
  397.     gs_makebitmappattern(&cc, &tile, false, pgs, NULL);
  398.     gs_setcolor(pgs, &cc);
  399.     gs_moveto(pgs, 50.0, 50.0);
  400.     gs_lineto(pgs, 300.0, 50.0);
  401.     gs_lineto(pgs, 50.0, 300.0);
  402.     gs_closepath(pgs);
  403.     gs_setrgbcolor(pgs, 1.0, 0.0, 0.0);
  404.     gs_gsave(pgs);
  405.     gs_fill(pgs);
  406.     gs_grestore(pgs);
  407.     gs_setpattern(pgs, &cc);
  408.     gs_eofill(pgs);
  409.     return 0;
  410. }
  411.  
  412. /* ---------------- Test program 3 ---------------- */
  413. /* Exercise RasterOp a little. */
  414. /* Currently, this only works with monobit devices. */
  415.  
  416. private int
  417. test3(gs_state * pgs, gs_memory_t * mem)
  418. {
  419.     gx_device *dev = gs_currentdevice(pgs);
  420.     gx_color_index black = gx_device_black(dev);
  421.     gx_color_index white = gx_device_white(dev);
  422.     gx_color_index black2[2];
  423.     gx_color_index black_white[2];
  424.     gx_color_index white_black[2];
  425.     long pattern[max(align_bitmap_mod / sizeof(long), 1) * 4];
  426.  
  427. #define pbytes ((byte *)pattern)
  428.     gx_tile_bitmap tile;
  429.  
  430.     black2[0] = black2[1] = black;
  431.     black_white[0] = white_black[1] = black;
  432.     black_white[1] = white_black[0] = white;
  433.     pbytes[0] = 0xf0;
  434.     pbytes[align_bitmap_mod] = 0x90;
  435.     pbytes[align_bitmap_mod * 2] = 0x90;
  436.     pbytes[align_bitmap_mod * 3] = 0xf0;
  437.     tile.data = pbytes;
  438.     tile.raster = align_bitmap_mod;
  439.     tile.size.x = tile.size.y = 4;
  440.     tile.id = gs_next_ids(1);
  441.     tile.rep_width = tile.rep_height = 4;
  442.     (*dev_proc(dev, copy_rop))
  443.     (dev, NULL, 0, 0, gx_no_bitmap_id, black2,
  444.      &tile, white_black, 100, 100, 150, 150, 0, 0, rop3_T);
  445.     (*dev_proc(dev, copy_rop))
  446.     (dev, NULL, 0, 0, gx_no_bitmap_id, black2,
  447.      NULL, NULL, 120, 120, 110, 110, 0, 0, ~rop3_S & rop3_1);
  448.     (*dev_proc(dev, copy_rop))
  449.     (dev, NULL, 0, 0, gx_no_bitmap_id, black2,
  450.      &tile, white_black, 110, 110, 130, 130, 0, 0, rop3_T ^ rop3_D);
  451. #undef pbytes
  452.     return 0;
  453. }
  454.  
  455. /* ---------------- Test program 4 ---------------- */
  456. /* Set the resolution dynamically. */
  457.  
  458. private int
  459. test4(gs_state * pgs, gs_memory_t * mem)
  460. {
  461.     gs_c_param_list list;
  462.     float resv[2];
  463.     gs_param_float_array ares;
  464.     int code;
  465.     gx_device *dev = gs_currentdevice(pgs);
  466.  
  467.     gs_c_param_list_write(&list, mem);
  468.     resv[0] = resv[1] = 100;
  469.     ares.data = resv;
  470.     ares.size = 2;
  471.     ares.persistent = true;
  472.     code = param_write_float_array((gs_param_list *) & list,
  473.                    "HWResolution", &ares);
  474.     if (code < 0) {
  475.     lprintf1("Writing HWResolution failed: %d\n", code);
  476.     exit(1);
  477.     }
  478.     gs_c_param_list_read(&list);
  479.     code = gs_putdeviceparams(dev, (gs_param_list *) & list);
  480.     gs_c_param_list_release(&list);
  481.     if (code < 0) {
  482.     lprintf1("Setting HWResolution failed: %d\n", code);
  483.     exit(1);
  484.     }
  485.     gs_initmatrix(pgs);
  486.     gs_initclip(pgs);
  487.     if (code == 1) {
  488.     code = (*dev_proc(dev, open_device)) (dev);
  489.     if (code < 0) {
  490.         lprintf1("Reopening device failed: %d\n", code);
  491.         exit(1);
  492.     }
  493.     }
  494.     gs_moveto(pgs, 0.0, 72.0);
  495.     gs_rlineto(pgs, 72.0, 0.0);
  496.     gs_rlineto(pgs, 0.0, 72.0);
  497.     gs_closepath(pgs);
  498.     gs_stroke(pgs);
  499.     return 0;
  500. }
  501.  
  502. /* ---------------- Test program 5 ---------------- */
  503. /* Test masked (and non-masked) images. */
  504.  
  505. private int
  506. test5(gs_state * pgs, gs_memory_t * mem)
  507. {
  508.     gx_device *dev = gs_currentdevice(pgs);
  509.     gx_image_enum_common_t *info;
  510.     gx_image_plane_t planes[5];
  511.     gx_drawing_color dcolor;
  512.     int code;
  513.     static const byte data3[] =
  514.     {
  515.     0x00, 0x44, 0x88, 0xcc,
  516.     0x44, 0x88, 0xcc, 0x00,
  517.     0x88, 0xcc, 0x00, 0x44,
  518.     0xcc, 0x00, 0x44, 0x88
  519.     };
  520.  
  521.     /*
  522.      * Neither ImageType 3 nor 4 needs a current color,
  523.      * but some intermediate code assumes it's valid.
  524.      */
  525.     color_set_pure(&dcolor, 0);
  526.  
  527.     /* Scale everything up, and fill the background. */
  528.     {
  529.     gs_matrix mat;
  530.  
  531.     gs_currentmatrix(pgs, &mat);
  532.     mat.xx = gs_copysign(98.6, mat.xx);
  533.     mat.yy = gs_copysign(98.6, mat.yy);
  534.     mat.tx = floor(mat.tx) + 0.499;
  535.     mat.ty = floor(mat.ty) + 0.499;
  536.     gs_setmatrix(pgs, &mat);
  537.     }
  538.     gs_setrgbcolor(pgs, 1.0, 0.9, 0.9);
  539.     fill_rect1(pgs, 0.25, 0.25, 4.0, 6.0);
  540.     gs_setrgbcolor(pgs, 0.5, 1.0, 0.5);
  541.  
  542. #if 0
  543.     /* Make things a little more interesting.... */
  544.     gs_translate(pgs, 1.0, 1.0);
  545.     gs_rotate(pgs, 10.0);
  546.     gs_scale(pgs, 1.3, 0.9);
  547. #endif
  548.  
  549. #define do_image(image, idata)\
  550.   BEGIN\
  551.   code = gx_device_begin_typed_image(dev, (gs_imager_state *)pgs, NULL,\
  552.      (gs_image_common_t *)&image, NULL, &dcolor, NULL, mem, &info);\
  553.   /****** TEST code >= 0 ******/\
  554.   planes[0].data = idata;\
  555.   planes[0].data_x = 0;\
  556.   planes[0].raster = (image.Height * image.BitsPerComponent + 7) >> 3;\
  557.   code = gx_image_plane_data(info, planes, image.Height);\
  558.   /****** TEST code == 1 ******/\
  559.   code = gx_image_end(info, true);\
  560.   /****** TEST code >= 0 ******/\
  561.   END
  562.  
  563. #define W 4
  564. #define H 4
  565.  
  566.     /* Test an unmasked image. */
  567.     gs_gsave(pgs);
  568.     {
  569.     gs_image1_t image1;
  570.     void *info1;
  571.  
  572.     gs_image_t_init_gray(&image1, (const gs_imager_state *)pgs);
  573.     /* image */
  574.     image1.ImageMatrix.xx = W;
  575.     image1.ImageMatrix.yy = -H;
  576.     image1.ImageMatrix.ty = H;
  577.     /* data_image */
  578.     image1.Width = W;
  579.     image1.Height = H;
  580.     image1.BitsPerComponent = 8;
  581.  
  582.     gs_translate(pgs, 0.5, 4.0);
  583.     code = gx_device_begin_image(dev, (gs_imager_state *) pgs,
  584.                      &image1, gs_image_format_chunky,
  585.                      NULL, &dcolor, NULL, mem, &info1);
  586. /****** TEST code >= 0 ******/
  587.     planes[0].data = data3;
  588.     planes[0].data_x = 0;
  589.     planes[0].raster =
  590.         (image1.Height * image1.BitsPerComponent + 7) >> 3;
  591.     /* Use the old image_data API. */
  592.     code = gx_image_data(info1, &planes[0].data, 0,
  593.                  planes[0].raster, image1.Height);
  594. /****** TEST code == 1 ******/
  595.     code = gx_image_end(info1, true);
  596. /****** TEST code >= 0 ******/
  597.     }
  598.     gs_grestore(pgs);
  599.  
  600.     /* Test an explicitly masked image. */
  601.     gs_gsave(pgs);
  602.     {
  603.     gs_image3_t image3;
  604.     static const byte data3mask[] =
  605.     {
  606.         0x60,
  607.         0x90,
  608.         0x90,
  609.         0x60
  610.     };
  611.     static const byte data3x2mask[] =
  612.     {
  613.         0x66,
  614.         0x99,
  615.         0x99,
  616.         0x66,
  617.         0x66,
  618.         0x99,
  619.         0x99,
  620.         0x66
  621.     };
  622.  
  623.     gs_image3_t_init(&image3, gs_current_DeviceGray_space(pgs),
  624.              interleave_scan_lines);
  625.     /* image */
  626.     image3.ImageMatrix.xx = W;
  627.     image3.ImageMatrix.yy = -H;
  628.     image3.ImageMatrix.ty = H;
  629.     /* data_image */
  630.     image3.Width = W;
  631.     image3.Height = H;
  632.     image3.BitsPerComponent = 8;
  633.     /* MaskDict */
  634.     image3.MaskDict.ImageMatrix = image3.ImageMatrix;
  635.     image3.MaskDict.Width = image3.Width;
  636.     image3.MaskDict.Height = image3.Height;
  637.  
  638.     /* Display with 1-for-1 mask and image. */
  639.     gs_translate(pgs, 0.5, 2.0);
  640.     code = gx_device_begin_typed_image(dev, (gs_imager_state *) pgs,
  641.                        NULL, (gs_image_common_t *) & image3,
  642.                        NULL, &dcolor, NULL, mem, &info);
  643. /****** TEST code >= 0 ******/
  644.     planes[0].data = data3mask;
  645.     planes[0].data_x = 0;
  646.     planes[0].raster = (image3.MaskDict.Height + 7) >> 3;
  647.     planes[1].data = data3;
  648.     planes[1].data_x = 0;
  649.     planes[1].raster =
  650.         (image3.Height * image3.BitsPerComponent + 7) >> 3;
  651.     code = gx_image_plane_data(info, planes, image3.Height);
  652. /****** TEST code == 1 ******/
  653.     code = gx_image_end(info, true);
  654. /****** TEST code >= 0 ******/
  655.  
  656.     /* Display with 2-for-1 mask and image. */
  657.     image3.MaskDict.ImageMatrix.xx *= 2;
  658.     image3.MaskDict.ImageMatrix.yy *= 2;
  659.     image3.MaskDict.ImageMatrix.ty *= 2;
  660.     image3.MaskDict.Width *= 2;
  661.     image3.MaskDict.Height *= 2;
  662.     gs_translate(pgs, 1.5, 0.0);
  663.     code = gx_device_begin_typed_image(dev, (gs_imager_state *) pgs,
  664.                        NULL, (gs_image_common_t *) & image3,
  665.                        NULL, &dcolor, NULL, mem, &info);
  666. /****** TEST code >= 0 ******/
  667.     planes[0].data = data3x2mask;
  668.     planes[0].raster = (image3.MaskDict.Width + 7) >> 3;
  669.     {
  670.         int i;
  671.  
  672.         for (i = 0; i < H; ++i) {
  673.         planes[1].data = 0;
  674.         code = gx_image_plane_data(info, planes, 1);
  675.         planes[0].data += planes[0].raster;
  676. /****** TEST code == 0 ******/
  677.         planes[1].data = data3 + i * planes[1].raster;
  678.         code = gx_image_plane_data(info, planes, 1);
  679.         planes[0].data += planes[0].raster;
  680. /****** TEST code >= 0 ******/
  681.         }
  682.     }
  683. /****** TEST code == 1 ******/
  684.     code = gx_image_end(info, true);
  685. /****** TEST code >= 0 ******/
  686.     }
  687.     gs_grestore(pgs);
  688.  
  689.     /* Test a chroma-keyed masked image. */
  690.     gs_gsave(pgs);
  691.     {
  692.     gs_image4_t image4;
  693.     const byte *data4 = data3;
  694.  
  695.     gs_image4_t_init(&image4, gs_current_DeviceGray_space(pgs));
  696.     /* image */
  697.     image4.ImageMatrix.xx = W;
  698.     image4.ImageMatrix.yy = -H;
  699.     image4.ImageMatrix.ty = H;
  700.     /* data_image */
  701.     image4.Width = W;
  702.     image4.Height = H;
  703.     image4.BitsPerComponent = 8;
  704.  
  705.     /* Display with a single mask color. */
  706.     gs_translate(pgs, 0.5, 0.5);
  707.     image4.MaskColor_is_range = false;
  708.     image4.MaskColor[0] = 0xcc;
  709.     do_image(image4, data4);
  710.  
  711.     /* Display a second time with a color range. */
  712.     gs_translate(pgs, 1.5, 0.0);
  713.     image4.MaskColor_is_range = true;
  714.     image4.MaskColor[0] = 0x40;
  715.     image4.MaskColor[1] = 0x90;
  716.     do_image(image4, data4);
  717.     }
  718.     gs_grestore(pgs);
  719.  
  720. #undef W
  721. #undef H
  722. #undef do_image
  723.     return 0;
  724. }
  725.  
  726. /* ---------------- Test program 6 ---------------- */
  727. /* Test the C API for CIE CRDs, and color snapping. */
  728.  
  729. private void
  730. spectrum(gs_state * pgs, int n)
  731. {
  732.     float den = n;
  733.     float den1 = n - 1;
  734.     float den2 = (n * 2 - 1) * n;
  735.     int a, b, c;
  736.  
  737.     for (a = 0; a < n; ++a)
  738.     for (b = 0; b < n; ++b)
  739.         for (c = 0; c < n; ++c) {
  740.         double size = (n * 2 - c * 2 - 1) / den2;
  741.         gs_client_color cc;
  742.  
  743.         cc.paint.values[0] = a / den1;
  744.         cc.paint.values[1] = b / den1;
  745.         cc.paint.values[2] = c / den1;
  746.         gs_setcolor(pgs, &cc);
  747.         fill_rect1(pgs,
  748.                a / den + c / den2, b / den + c / den2,
  749.                size, size);
  750.         }
  751. }
  752. private float
  753. render_abc(floatp v, const gs_cie_render * ignore_crd)
  754. {
  755.     return v / 2;
  756. }
  757. private int
  758. set_cmap_method(gx_device_cmap *cmdev, gx_device_color_mapping_method_t method,
  759.         gs_state *pgs, gs_memory_t *mem)
  760. {
  761.     gs_c_param_list list;
  762.     int cmm = method;
  763.  
  764.     gs_c_param_list_write(&list, mem);
  765.     param_write_int((gs_param_list *)&list, "ColorMappingMethod", &cmm);
  766.     gs_c_param_list_read(&list);
  767.     gs_putdeviceparams((gx_device *)cmdev, (gs_param_list *)&list);
  768.     gs_c_param_list_release(&list);
  769.     gs_setdevice_no_init(pgs, (gx_device *)cmdev);
  770.     return 0;
  771. }
  772. private int
  773. test6(gs_state * pgs, gs_memory_t * mem)
  774. {
  775.     gs_color_space *pcs;
  776.     gs_cie_abc *pabc;
  777.     gs_cie_render *pcrd;
  778.     static const gs_vector3 white_point =
  779.     {1, 1, 1};
  780.     static const gs_cie_render_proc3 encode_abc =
  781.     {
  782.     {render_abc, render_abc, render_abc}
  783.     };
  784.     gx_device_cmap *cmdev;
  785.     int code;
  786.  
  787.     gs_scale(pgs, 150.0, 150.0);
  788.     gs_translate(pgs, 0.5, 0.5);
  789.     gs_setcolorspace(pgs, gs_current_DeviceRGB_space(pgs));
  790.     spectrum(pgs, 5);
  791.     gs_translate(pgs, 1.2, 0.0);
  792.     /* We must set the CRD before the color space. */
  793.     code = gs_cie_render1_build(&pcrd, mem, "test6");
  794.     if (code < 0)
  795.     return code;
  796.     gs_cie_render1_initialize(pcrd, NULL, &white_point, NULL,
  797.                   NULL, NULL, NULL,
  798.                   NULL, NULL, NULL,
  799.                   NULL, &encode_abc, NULL,
  800.                   NULL);
  801.     gs_setcolorrendering(pgs, pcrd);
  802.     gs_cspace_build_CIEABC(&pcs, NULL, mem);
  803.     /* There should be an API for initializing CIE color spaces too.... */
  804.     pabc = pcs->params.abc;
  805.     pabc->common.points.WhitePoint = white_point;
  806.     gs_cie_abc_complete(pabc);
  807.     /* End of initializing the color space. */
  808.     gs_setcolorspace(pgs, pcs);
  809.     spectrum(pgs, 5);
  810.     /* Now test color snapping. */
  811.     cmdev =
  812.     gs_alloc_struct_immovable(mem, gx_device_cmap, &st_device_cmap,
  813.                   "cmap device");
  814.     gdev_cmap_init(cmdev, gs_currentdevice(pgs),
  815.            device_cmap_snap_to_primaries);
  816.     gs_setdevice_no_init(pgs, (gx_device *) cmdev);
  817.     gs_setrgbcolor(pgs, 0.0, 0.0, 0.0);        /* back to DeviceRGB space */
  818.     gs_translate(pgs, -1.2, 1.2);
  819.     spectrum(pgs, 5);
  820.     gs_translate(pgs, 1.2, 0.0);
  821.     set_cmap_method(cmdev, device_cmap_monochrome, pgs, mem);
  822.     spectrum(pgs, 5);
  823.     gs_translate(pgs, -1.2, 1.2);
  824.     set_cmap_method(cmdev, device_cmap_color_to_black_over_white, pgs, mem);
  825.     spectrum(pgs, 5);
  826.     return 0;
  827. }
  828.  
  829. /* ---------------- Test program 7 ---------------- */
  830. /* Test the C API for non-monotonic halftones. */
  831.  
  832. private int
  833. test7(gs_state * pgs, gs_memory_t * mem)
  834. {
  835.     /* Define a non-monotonic 4 x 4 halftone with 4 gray levels. */
  836.     static const byte masks[1 * 4 * 4] =
  837.     {
  838.     /* 0% */
  839.     0x00, 0x00, 0x00, 0x00,
  840.     /* 25% */
  841.     0x80, 0x40, 0x20, 0x10,
  842.     /* 50% */
  843.     0xa0, 0xa0, 0x50, 0x50,
  844.     /* 75% */
  845.     0xd0, 0xe0, 0x70, 0xb0
  846.     };
  847.     gs_ht *pht;
  848.     int code;
  849.     int i;
  850.  
  851.     /* Fabricate a Type 5 halftone. */
  852.     code = gs_ht_build(&pht, 1, mem);
  853.     dprintf1("ht build code = %d\n", code);
  854.     code = gs_ht_set_mask_comp(pht, 0, gs_ht_separation_Default,
  855.                    4, 4, 4, masks, NULL, NULL);
  856.     dprintf1("set mask code = %d\n", code);
  857.     code = gs_sethalftone(pgs, pht);
  858.     dprintf1("sethalftone code = %d\n", code);
  859.     for (i = 0; i <= 4; ++i) {
  860.     gs_setgray(pgs, i / 4.0);
  861.     fill_rect1(pgs, 100 + i * 100, 100, 50, 50);
  862.     }
  863.     return 0;
  864. }
  865.  
  866. /* ---------------- Test program 8 ---------------- */
  867. /* Test partially transparent patterns */
  868.  
  869. private int
  870. test8(gs_state * pgs, gs_memory_t * mem)
  871. {
  872.     /*
  873.      * Define a 16 x 16 pattern using a 4-entry palette
  874.      * (white, red, green, black).
  875.      */
  876.     static const byte pdata[] =
  877.     {
  878.     0x7f, 0xff, 0x00, 0x03,
  879.     0x7f, 0xff, 0x00, 0x0c,
  880.     0x50, 0x00, 0x00, 0x30,
  881.     0x50, 0x00, 0x00, 0xc0,
  882.     0x50, 0x00, 0x03, 0x00,
  883.     0x50, 0x00, 0x0c, 0x00,
  884.     0x50, 0x00, 0x30, 0x00,
  885.     0x50, 0x00, 0xc0, 0x00,
  886.     0xf0, 0x00, 0xc0, 0x00,
  887.     0xf0, 0x00, 0x30, 0x00,
  888.     0xf0, 0x00, 0x0c, 0x00,
  889.     0xf0, 0x00, 0x03, 0x00,
  890.     0xf0, 0x00, 0x00, 0xc0,
  891.     0xf0, 0x00, 0x00, 0x30,
  892.     0xea, 0x55, 0xaa, 0x5c,
  893.     0xea, 0x55, 0xaa, 0x57,
  894.     };
  895.     gs_depth_bitmap ptile;
  896.     gs_const_string table;
  897.     gs_color_space *pcs;
  898.     gs_client_color ccolor;
  899.  
  900.     table.data =
  901.     (const byte *)"\377\377\377\377\000\000\000\377\000\000\000\000";
  902.     table.size = 12;
  903.     gs_cspace_build_Indexed(&pcs,
  904.                 gs_current_DeviceRGB_space(pgs),
  905.                 4,
  906.                 &table,
  907.                 mem);
  908.     ptile.data = pdata;
  909.     ptile.raster = 4;
  910.     ptile.size.x = ptile.size.y = 16;
  911.     ptile.id = gs_no_bitmap_id;
  912.     ptile.pix_depth = 2;
  913.     ptile.num_comps = 1;
  914.     gs_makepixmappattern(&ccolor, &ptile, false /*mask */ , NULL /*pmat */ ,
  915.              gs_no_id, pcs, 0 /*white_index */ , pgs, mem);
  916.     {
  917.     gs_rect r;
  918.  
  919.     r.p.x = 100;
  920.     r.p.y = 100;
  921.     r.q.x = 200;
  922.     r.q.y = 200;
  923.     gs_setrgbcolor(pgs, 1.0, 1.0, 0.0);
  924.     gs_rectfill(pgs, &r, 1);
  925.     gs_setpattern(pgs, &ccolor);
  926.     gs_settexturetransparent(pgs, true);
  927.     gs_rectfill(pgs, &r, 1);
  928.     r.p.x += 150;
  929.     r.q.x += 150;
  930.     gs_setrgbcolor(pgs, 1.0, 1.0, 0.0);
  931.     gs_rectfill(pgs, &r, 1);
  932.     gs_setpattern(pgs, &ccolor);
  933.     gs_settexturetransparent(pgs, false);
  934.     gs_rectfill(pgs, &r, 1);
  935.     }
  936.     return 0;
  937. }
  938.  
  939.  
  940. #ifdef CAPTURE
  941.  
  942. /* ---------------- Test program 10 ---------------- */
  943. /* Replay captured data for printer output. */
  944.  
  945. private const char outfile[] = "t.pbm";
  946. private const float ypage_wid = 11.0;
  947. private const float xpage_len = 17.0;
  948. private const int rotate_value = 0;
  949. private const float scale_x = 0.45;
  950. private const float scale_y = 0.45;
  951. private const float xmove_origin = 0.0;
  952. private const float ymove_origin = 0.0;
  953.  
  954. private int
  955. test10(gs_state * pgs, gs_memory_t * mem)
  956. {
  957.     gs_c_param_list list;
  958.     gs_param_string nstr, OFstr;
  959.     gs_param_float_array PSa;
  960.     gs_param_float_array HWRa;
  961.     gs_param_int_array HWSa;
  962.     int HWSize[2];
  963.     float HWResolution[2], PageSize[2];
  964.     long MaxBitmap;
  965.     int code;
  966.     gx_device *dev = gs_currentdevice(pgs);
  967.     float xlate_x, xlate_y;
  968.     gs_rect cliprect;
  969.  
  970.     gs_c_param_list_write(&list, mem);
  971.     code = gs_getdeviceparams(dev, (gs_param_list *) & list);
  972.     if (code < 0) {
  973.     lprintf1("getdeviceparams failed! code = %d\n", code);
  974.     exit(1);
  975.     }
  976.     gs_c_param_list_read(&list);
  977.     code = param_read_string((gs_param_list *) & list, "Name", &nstr);
  978.     if (code < 0) {
  979.     lprintf1("reading Name failed! code = %d\n", code);
  980.     exit(1);
  981.     }
  982.     code = param_read_int_array((gs_param_list *) & list,
  983.                 "HWSize", &HWSa);
  984.     if (code < 0) {
  985.     lprintf1("reading HWSize failed! code = %d\n", code);
  986.     exit(1);
  987.     }
  988.     eprintf3("HWSize[%d] = [ %d, %d ]\n", HWSa.size,
  989.          HWSa.data[0], HWSa.data[1]);
  990.     code = param_read_float_array((gs_param_list *) & list,
  991.                   "HWResolution", &HWRa);
  992.     if (code < 0) {
  993.     lprintf1("reading Resolution failed! code = %d\n", code);
  994.     exit(1);
  995.     }
  996.     eprintf3("HWResolution[%d] = [ %f, %f ]\n", HWRa.size,
  997.          HWRa.data[0], HWRa.data[1]);
  998.     code = param_read_float_array((gs_param_list *) & list,
  999.                   "PageSize", &PSa);
  1000.     if (code < 0) {
  1001.     lprintf1("reading PageSize failed! code = %d\n", code);
  1002.     exit(1);
  1003.     }
  1004.     eprintf3("PageSize[%d] = [ %f, %f ]\n", PSa.size,
  1005.          PSa.data[0], PSa.data[1]);
  1006.     code = param_read_long((gs_param_list *) & list,
  1007.                "MaxBitmap", &MaxBitmap);
  1008.     if (code < 0) {
  1009.     lprintf1("reading MaxBitmap failed! code = %d\n", code);
  1010.     exit(1);
  1011.     }
  1012.     eprintf1("MaxBitmap = %ld\n", MaxBitmap);
  1013.     /* Switch to param list functions to "write" */
  1014.     gs_c_param_list_write(&list, mem);
  1015.     /* Always set the PageSize. */
  1016.     PageSize[0] = 72.0 * ypage_wid;
  1017.     PageSize[1] = 72.0 * xpage_len;
  1018.     PSa.data = PageSize;
  1019.     code = param_write_float_array((gs_param_list *) & list,
  1020.                    "PageSize", &PSa);
  1021.     if (nstr.data[0] != 'v') {
  1022.     /* Set the OutputFile string file name */
  1023.     OFstr.persistent = false;
  1024.     OFstr.data = outfile;
  1025.     OFstr.size = strlen(outfile);
  1026.     code = param_write_string((gs_param_list *) & list,
  1027.                   "OutputFile", &OFstr);
  1028.     if (code < 0) {
  1029.         lprintf1("setting OutputFile name failed, code=%d\n",
  1030.              code);
  1031.         exit(1);
  1032.     }
  1033.     if (nstr.data[0] == 'x') {
  1034.         HWResolution[0] = HWResolution[1] = 72.0;
  1035.     } else {
  1036.         HWResolution[0] = HWResolution[1] = 360.0;
  1037.     }
  1038.     HWRa.data = HWResolution;
  1039.     HWSize[0] = (int)(HWResolution[0] * ypage_wid);
  1040.     HWSize[1] = (int)(HWResolution[1] * xpage_len);
  1041.     eprintf3("    HWSize = [%d,%d], HWResolution = %f dpi\n",
  1042.          HWSize[0], HWSize[1], HWResolution[0]);
  1043.     HWSa.data = HWSize;
  1044.     code = param_write_float_array((gs_param_list *) & list,
  1045.                        "HWResolution", &HWRa);
  1046.     code = param_write_int_array((gs_param_list *) & list,
  1047.                      "HWSize", &HWSa);
  1048.     MaxBitmap = 1000000L;
  1049.     code = param_write_long((gs_param_list *) & list,
  1050.                 "MaxBitmap", &MaxBitmap);
  1051.     }
  1052.     gs_c_param_list_read(&list);
  1053.     code = gs_putdeviceparams(dev, (gs_param_list *) & list);
  1054.     eprintf1("putdeviceparams: code=%d\n", code);
  1055.     gs_c_param_list_release(&list);
  1056.  
  1057.     gs_erasepage(pgs);
  1058.     gs_initgraphics(pgs);
  1059.     gs_clippath(pgs);
  1060.     gs_pathbbox(pgs, &cliprect);
  1061.     eprintf4("    cliprect = [[%g,%g],[%g,%g]]\n",
  1062.          cliprect.p.x, cliprect.p.y, cliprect.q.x, cliprect.q.y);
  1063.     gs_newpath(pgs);
  1064.  
  1065.     switch (((rotate_value + 270) / 90) & 3) {
  1066.     default:
  1067.     case 0:        /* 0 = 360 degrees in PS == 90 degrees in printer */
  1068.         xlate_x = cliprect.p.x;
  1069.         xlate_y = cliprect.p.y;
  1070.         break;
  1071.     case 1:        /* 90 degrees in PS = 180 degrees printer */
  1072.         xlate_x = cliprect.q.x;
  1073.         xlate_y = cliprect.p.y;
  1074.         break;
  1075.     case 2:        /* 180 degrees in PS == 270 degrees in printer */
  1076.         xlate_x = cliprect.q.x;
  1077.         xlate_y = cliprect.q.y;
  1078.         break;
  1079.     case 3:        /* 270 degrees in PS == 0 degrees in printer */
  1080.         xlate_x = cliprect.p.x;
  1081.         xlate_y = cliprect.q.y;
  1082.         break;
  1083.     }
  1084.     eprintf2("translate origin to [ %f, %f ]\n", xlate_x, xlate_y);
  1085.     gs_translate(pgs, xlate_x, xlate_y);
  1086.  
  1087.     /* further move (before rotate) by user requested amount */
  1088.     gs_translate(pgs, 72.0 * (float)xmove_origin, 72.0 * (float)ymove_origin);
  1089.  
  1090.     gs_rotate(pgs, (float)rotate_value + 270.0);
  1091.     gs_scale(pgs, scale_x * 72.0 / 2032.0,
  1092.          scale_y * 72.0 / 2032.0);
  1093.     gs_setlinecap(pgs, gs_cap_butt);
  1094.     gs_setlinejoin(pgs, gs_join_bevel);
  1095.     gs_setfilladjust(pgs, 0.0, 0.0);
  1096.  
  1097.     capture_exec(pgs);
  1098.     return 0;
  1099. }
  1100.  
  1101. #endif /* CAPTURE */
  1102.